package com.tsy.server.manage.service;

import com.tsy.server.component.websocket.model.BizCodeEnum;
import com.tsy.server.manage.model.dto.DeviceDTO;
import com.tsy.server.manage.model.dto.DeviceFirmwareUpgradeDTO;
import com.tsy.server.manage.model.dto.TopologyDeviceDTO;
import com.tsy.server.manage.model.param.DeviceQueryParam;
import com.dji.sdk.cloudapi.device.ControlSourceEnum;
import com.dji.sdk.cloudapi.device.DeviceOsdHost;
import com.dji.sdk.cloudapi.device.DockModeCodeEnum;
import com.dji.sdk.cloudapi.device.DroneModeCodeEnum;
import com.dji.sdk.config.version.GatewayManager;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.PaginationData;
import com.fasterxml.jackson.databind.JsonNode;

import java.util.List;
import java.util.Optional;

/**
 * @author sean.zhou
 * @date 2021/11/10
 * @version 0.1
 */
public interface IDeviceService {

    /**
     * 无人机离线。
     * @param deviceSn 无人机序列号
     */
    void subDeviceOffline(String deviceSn);

    /**
     * 网关离线。
     * @param gatewaySn 网关序列号
     */
    void gatewayOffline(String gatewaySn);

    /**
     * 网关设备上线时订阅其主题，并取消订阅子设备主题。
     * @param gateway 网关管理器
     */
    void gatewayOnlineSubscribeTopic(GatewayManager gateway);

    /**
     * 无人机上线时订阅网关和子设备的主题。
     * @param gateway 网关管理器
     */
    void subDeviceOnlineSubscribeTopic(GatewayManager gateway);

    /**
     * 网关设备下线时，取消订阅网关和子设备的主题。
     * @param gateway 网关管理器
     */
    void offlineUnsubscribeTopic(GatewayManager gateway);

    /**
     * 按不同查询条件获取设备数据。
     * @param param 查询参数
     * @return
     */
    List<DeviceDTO> getDevicesByParams(DeviceQueryParam param);

    /**
     * Web 侧业务接口：获取该工作空间下所有设备的完整信息。
     * @param projectId 项目ID
     * @return
     */
    List<DeviceDTO> getDevicesTopoForWeb(Long projectId);

    /**
     * 组装无人机的遥控器与载荷信息。
     * @param device 设备
     */
    void spliceDeviceTopo(DeviceDTO device);

    /**
     * 根据设备序列号查询设备拓扑信息。
     * @param sn 设备序列号
     * @return
     */
    Optional<TopologyDeviceDTO> getDeviceTopoForPilot(String sn);

    /**
     * 将单个设备信息转换为拓扑对象。
     * @param device 设备
     * @return
     */
    TopologyDeviceDTO deviceConvertToTopologyDTO(DeviceDTO device);

    /**
     * 同一工作空间内，服务端收到任一设备上线/离线/拓扑更新请求时，
     * 通过 WebSocket 广播设备上线/离线/拓扑更新给 PILOT，
     * PILOT 接收推送后会重新获取设备拓扑列表。
     * @param workspaceId 工作空间ID
     * @param deviceSn 设备序列号
     */
    void pushDeviceOfflineTopo(String workspaceId, String deviceSn);

    /**
     * 同一工作空间内，服务端收到任一设备上线/离线/拓扑更新请求时，
     * 通过 WebSocket 广播设备上线/离线/拓扑更新给 PILOT，
     * PILOT 接收推送后会重新获取设备拓扑列表。
     * @param workspaceId 工作空间ID
     * @param gatewaySn 网关序列号
     * @param deviceSn 设备序列号
     */
    void pushDeviceOnlineTopo(String workspaceId, String gatewaySn, String deviceSn);

    /**
     * 更新设备信息。
     * @param deviceDTO 设备数据
     * @return
     */
    Boolean updateDevice(DeviceDTO deviceDTO);

    /**
     * 绑定设备到组织或用户。
     * @param device 设备
     */
    Boolean bindDevice(DeviceDTO device);

    /**
     * 获取某个工作空间的绑定设备列表。
     * @param workspaceId 工作空间ID
     * @param page 页码
     * @param pageSize 分页大小
     * @param domain 设备域
     * @return
     */
    PaginationData<DeviceDTO> getBoundDevicesWithDomain(String workspaceId, Long page, Long pageSize, Integer domain);

    /**
     * 根据设备序列号解绑设备。
     * @param deviceSn 设备序列号
     */
    void unbindDevice(String deviceSn);

    /**
     * 根据设备序列号获取设备信息。
     * @param sn 设备序列号
     * @return device 设备
     */
    Optional<DeviceDTO> getDeviceBySn(String sn);

    /**
     * 为设备固件升级创建任务。
     * @param workspaceId 工作空间ID
     * @param upgradeDTOS 升级参数
     * @return
     */
    HttpResultResponse createDeviceOtaJob(String workspaceId, List<DeviceFirmwareUpgradeDTO> upgradeDTOS);

    /**
     * 设置无人机的属性参数。
     * @param workspaceId 工作空间ID
     * @param dockSn 机场序列号
     * @param param 属性参数
     * @return
     */
    int devicePropertySet(String workspaceId, String dockSn, JsonNode param);

    /**
     * 查询机场工作状态。
     * @param dockSn 机场序列号
     * @return
     */
    DockModeCodeEnum getDockMode(String dockSn);

    /**
     * 查询飞行器工作状态。
     * @param deviceSn 设备序列号
     * @return
     */
    DroneModeCodeEnum getDeviceMode(String deviceSn);

    /**
     * 检查机场是否处于 DRC 模式。
     * @param dockSn 机场序列号
     * @return
     */
    Boolean checkDockDrcMode(String dockSn);

    /**
     * 检查设备是否具备飞控权限。
     * @param gatewaySn 网关序列号
     * @return
     */
    Boolean checkAuthorityFlight(String gatewaySn);

    Integer saveDevice(DeviceDTO device);

    Boolean saveOrUpdateDevice(DeviceDTO device);

    void pushOsdDataToPilot(String workspaceId, String sn, DeviceOsdHost data);

    void pushOsdDataToWeb(String workspaceId, BizCodeEnum codeEnum, String sn, Object data);

    void updateFlightControl(DeviceDTO gateway, ControlSourceEnum controlSource);

    List<DeviceDTO> getUnboundProjectDevices(String workspaceId, String query);
}